---
title: Accessibility
redirect_from:
  - /components/card/accessibility/
---

## Accessibility

The Card component has been designed with accessibility in mind. It can be used with keyboard navigation and includes properties that enhance the experience for users of assistive technologies.

### Card accessibility props

| Name            | Type      | Description                                                                                                                                   |
| --------------- | :-------- | :-------------------------------------------------------------------------------------------------------------------------------------------- |
| labelClose      | `string`  | Label for the close button that's announced by screen readers, ensuring users understand the button's purpose.                                |
| dataA11ySection | `string`  | Optional identifier for the Card that can be used to improve screen reader navigation and identification of content sections.                 |
| titleAs         | `enum`    | Controls the semantic heading level (h1-h6) of the Card title, helping maintain proper document structure and heading hierarchy.              |
| loadingTitle    | `string`  | The title announced by screen readers when the card is in loading state. Required when `loading` is `true` and `loadingHidden` is not `true`. |
| loadingHidden   | `boolean` | If `true`, the loading state will be hidden from screen readers. Use when loading state is conveyed through other visible text on the page.   |

### CardSection accessibility props

| Name    | Type   | Description                                                                                                    |
| ------- | :----- | :------------------------------------------------------------------------------------------------------------- |
| titleAs | `enum` | Controls the semantic heading level of the CardSection title, allowing proper document hierarchy within Cards. |

### Keyboard navigation

#### Card component

Cards themselves are not focusable elements, but they may contain interactive elements like buttons, links, or form controls that are part of the card's content. These interactive elements follow standard keyboard navigation:

- Interactive elements within cards can be accessed using the `Tab` key
- When a Card contains the close button, it can be activated using `Enter` or `Space`

#### CardSection component

CardSection components have specific keyboard behaviors when they're expandable:

- Expandable sections can be toggled with `Enter` or `Space` when focused
- Focus is managed automatically when expanding/collapsing sections
- When multiple expandable sections exist in a Card, users can navigate between them using `Tab`

### Screen reader experience

#### Card component

Screen readers will announce:

- Card title level as specified by the `titleAs` prop (when provided anything other than `div`)
- The Card title as specified by the `title` prop (when provided)
- The close button with the custom label specified in `labelClose` prop

#### CardSection component

Screen readers will announce:

- The CardSection title as specified by the `title` prop
- The content within the section when expanded
- The expanded/collapsed state for expandable sections

### Important restrictions

- **CardSection with actions and expandability**: When using a clickable or expandable CardSection (`expandable={true}` or with `onClick` handler), avoid using the `actions` prop. If you must use it, ensure it only contains non-interactive elements. This prevents focus management issues and keyboard navigation confusion. Interactive elements in this context can create conflicts with the expanding functionality, leading to poor accessibility and usability.

Example of what to avoid:

```jsx
<CardSection
  expandable
  title="Flight details"
  actions={<Button>Edit</Button>} // Avoid interactive elements here
>
  {/* content */}
</CardSection>
```

Recommended approach:

```jsx
<CardSection
  expandable
  title="Flight details"
  actions={<Badge type="info">Economy</Badge>} // Non-interactive element is acceptable
>
  {/* content */}
</CardSection>
```

Also, Button component can be passed to the `actions` prop, but it should be non-interactive (ie. setting `asComponent="div"` and not defining `onClick`).

```jsx
<CardSection
  expandable
  title="Flight details"
  actions={<Button asComponent="div">Open</Button>} // Non-interactive element is acceptable
>
  {/* content */}
</CardSection>
```

### Best practices

#### Card best practices

- Use semantic heading levels with the `titleAs` prop to maintain proper document structure
- Provide a descriptive `labelClose` that clearly explains the action (e.g., "Close flight details")
- When creating complex page layouts and using SkipNavigation component on the page, you can use the `dataA11ySection` prop connect the Card with this component

#### CardSection best practices

- Avoid placing interactive elements in the `actions` prop of expandable CardSection components
- Maintain logical heading hierarchy between Card titles and CardSection titles

### Loading state accessibility

When using the Card's loading state, you must provide either a descriptive loading message or explicitly hide it from screen readers:

- Use `loadingTitle` to provide a descriptive message that will be announced to screen readers
- Use `loadingHidden` to hide the loading state from screen readers when the loading state is conveyed through other visible text on the page

```jsx
// Accessible loading state with descriptive message
<Card
  loading
  loadingTitle="Loading flight details"
>
  {/* content */}
</Card>

// Loading state hidden from screen readers because loading state
// is conveyed through other visible text on the page
<Card
  loading
  loadingHidden
>
  {/* content */}
</Card>
```

### Examples with accessibility features

#### Basic Card with accessibility props

```jsx
<Card
  title="Flight details"
  titleAs="h3"
  dataA11ySection="flight-summary"
  labelClose="Close flight details"
  onClose={() => {}}
>
  <CardSection>
    <Stack direction="column" spacing="100">
      <Text>Prague to Barcelona</Text>
      <Text type="secondary">June 21, 2023</Text>
    </Stack>
  </CardSection>
</Card>
```

Screen readers will announce heading level 3 of "Flight details", followed by the title of the card ("Flight details"), with a close button labeled "Close flight details", followed by the content of the card.

#### Card with expandable sections

```jsx
<Card title="Trip itinerary" titleAs="h2" dataA11ySection="trip-details">
  <CardSection expandable initialExpanded title="Flight information" titleAs="h3">
    <Text>Prague to Barcelona</Text>
    <Text type="secondary">June 21, 2023</Text>
  </CardSection>
  <CardSection expandable title="Hotel details" titleAs="h3">
    <Text>Hotel Barcelona</Text>
    <Text type="secondary">Check-in: June 21, 2023</Text>
  </CardSection>
</Card>
```

Screen readers will announce a section identified as `trip-details` with a heading level 2 of "Trip itinerary", followed by expandable sections with appropriate heading levels. The first section will be initially expanded.
